﻿using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using game.character.battle;
using game.character.weapon;
using lumo;
using lumo.display.object2D;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using lumo.display.animation2D;

namespace game.character.enemy
{

    /// <summary>
    /// The player.
    /// </summary>
    public class EnemySquid : EnemyBase
    {

        protected const string _Texture = "Graphics/Enemies/Squid";
        protected const int _Life = 1000;
        protected const float _Hit = 1000;

        /// <summary>
        /// Constructor for RedEnemy.
        /// </summary>
        public EnemySquid(LumoComponent component, GameMap map, Tiled.Object tiledObject)
            : base(component, map, tiledObject)
        {
            Battler = new GameEnemy(_Life);
            Battler.HitRate = _Hit;

            // Save the texture and some screen parameters.
            Texture = component.Content.Load<Texture2D>(_Texture);
            Weapon = new EnemyWeapon(_LumoComponent.Content.Load<Texture2D>("Graphics/Weapons/Bullet01"));
        }

        /// <summary>
        /// Update the character.
        /// </summary>
        /// <param name="component">Update using lumo</param>
        protected override void CreateBody()
        {
            // Create Submarine Body.
            Body = BodyFactory.CreateRectangle(Global.Map.World, Texture.Width / 4 / Global.PhysicsScale, Texture.Height / Global.PhysicsScale, 1f);
            Body.BodyType = BodyType.Dynamic;
            Body.IsSensor = true;
            Body.IgnoreGravity = true;
            Body.CollisionCategories = Global.PhysicsCategory.Enemy;
            Body.CollidesWith = Global.PhysicsCategory.Actor | Global.PhysicsCategory.ActorBullet;
            Body.LinearDamping = 1.0f;
            Body.Restitution = 0.25f;
        }
        protected override void SetupParameters()
        {
            
            // Setup The coordinates
            Position = new Vector2(_TiledObject.X, _TiledObject.Y);
            SourceRectangle = new Rectangle(0, 0, Texture.Width / 4, Texture.Height);
            ScreenOrigin = new Vector2(Texture.Width / 8, Texture.Height / 2);
        }

        protected override void SetupAI()
        {
            float Speed         = GetFloatProperty("Speed", 300f);
            float FleeRange     = GetFloatProperty("FleeRange", 150.0f);
            float NeutralRange  = GetFloatProperty("NeutralRange", 400.0f);
            float SightRange    = GetFloatProperty("SightRange", 1200.0f);
            float MoveDelay     = GetFloatProperty("MoveDelay", 2000.0f);
            float ShootDelay    = GetFloatProperty("ShootDelay", 2000.0f);

            // Delay actions
            AIOnTimer(MoveDelay, MoveDelay, () => "MoveTimer");
            AIOnTimer(MoveDelay / 4, MoveDelay / 4, () => "FleeMoveTimer");
            AIOnTimer(ShootDelay, ShootDelay, () => "ShootTimer");

            // Shoot action
            AIAction ShootAction = AIOnRange(
                SightRange,
                _GameMap.Player,
                () =>
                {
                    Weapon.Shoot(BulletManager, Position, _GameMap.Player.Position, Vector2.Zero);
                    return null;
                }
            );
            ShootAction.OnGroups("ShootTimer");

            // Flee action
            AIAction FleeAction = AIOnRange(
                FleeRange,
                _GameMap.Player,
                () =>
                {
                    Vector2 Direction = -Vector2.Normalize(_GameMap.Player.Position - this.Position);
                    this.Body.LinearVelocity = Vector2.Multiply(Direction, Speed / Global.PhysicsScale);
                    return "Fleeing";
                }
            );

            // Flee action
            AIAction NeutralAction = AIOnRange( NeutralRange, _GameMap.Player, () => "Neutral" );

            // Flee action
            AIAction FollowAction = AIOnRange(
                SightRange,
                _GameMap.Player,
                () =>
                {
                    Vector2 Direction = Vector2.Normalize(_GameMap.Player.Position - this.Position);
                    this.Body.LinearVelocity = Vector2.Multiply(Direction, Speed / Global.PhysicsScale);
                    return "Following";
                }
            );
            FleeAction.OnGroups("FleeMoveTimer");
            FollowAction.OnGroupsSelective( 
                new string[] { "MoveTimer" }, // On Move Timer
                new string[] { "Fleeing", "Neutral" }   // On Not Fleeing nor neutral
            );

            // Flee action
            AIOnRangePattern(float.PositiveInfinity, _GameMap.Player, 0.1f, AIRangePattern.Lock);

            // Damage the object on contact
            AIDamageOnContact(_GameMap.Player, "Damaging");

            // Animation.
            FrameAnimation2D Animation = new FrameAnimation2D(4, 1, new uint[] { 0, 0, 0, 0, 0, 1, 2, 3 }, 800.0f, Smooth.Arrival, Loop.Reset, this);
            AIOnUpdate(
                () =>
                {
                    Animation.Update(_LumoComponent);
                    return null;
                }
            );
               
        }

    }

}